import os
import tkinter as tk
from tkinter import ttk
from typing import Dict, List, Tuple, Set
from MelodieFuncFlow import *
from ..models import DocInfo, Finding
from ..api import FILE_OPEN_HANDLER
from .high_dpi import scale_ratio
from .layouts import Horizontal


class FindingsShow(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)

        style = ttk.Style()
        style.configure("Treeview", rowheight=int(20 * scale_ratio()))
        # style.configure("Treeview", rowheight=60)
        # rowheight = style.lookup("Treeview", "rowheight")
        # # print("Row height:", rowheight)

        self.tree_frame = Horizontal(self)

        self.tree = ttk.Treeview(self.tree_frame, height=10)
        self.tree.bind("<Double-1>", self.on_node_click)

        self.tree_frame.add(self.tree, True)

        self.scroll = tk.Scrollbar(
            self.tree_frame, orient="vertical", command=self.tree.yview
        )

        self.tree.configure(yscrollcommand=self.scroll.set)
        self.tree_frame.add(self.scroll)
        self.tree_frame.pack(fill="both", expand=True)

    def on_node_click(self, event):
        item = self.tree.selection()[0]
        result = self.tree.item(item, "values")
        if len(result) == 2:
            file, text = result
            text = text if len(text) <= 30 else text[:30]
            ext = os.path.splitext(file)[1]
            FILE_OPEN_HANDLER[ext](file, text)

    def open_children_recursive(self, parent):
        self.tree.item(parent, open=True)
        for child in self.tree.get_children(parent):
            self.open_children_recursive(child)

    def open_children(self, parent):
        for child in self.tree.get_children(parent):
            child.item(parent, open=True)

    def update_data(self, findings: List[Finding]):
        for child in self.tree.get_children():
            self.tree.delete(child)
        # 遍历数据，为每个数据项创建一个子节点
        for i, item in enumerate(findings):
            file_id = self.tree.insert(
                "",
                "end",
                text=f"{i+1}. " + os.path.basename(item.file),
                values=item.file,
            )
            for paragraph in item.paragraphs:
                self.tree.insert(
                    file_id,
                    "end",
                    text=paragraph,
                    values=(item.file, paragraph),
                )
            if i < 10:
                self.open_children_recursive(file_id)

    def doc_info_unique(self, files: List[DocInfo]):
        s = set()
        unique_docinfos: List[DocInfo] = []
        for i, doc_info in enumerate(files):
            last_length = len(s)
            s.add(os.path.normcase(doc_info.name))
            this_length = len(s)
            if this_length > last_length:
                unique_docinfos.append(doc_info)
        # unique_docinfos.sort(key=lambda info: info.modified_at, reverse=True)
        return unique_docinfos

    def update_data_reversed(self, findings: List[Finding]):
        """
        以内容为键，以文件名为值，制作映射
        """
        for child in self.tree.get_children():
            self.tree.delete(child)

        finding_items: Dict[str, List[str]] = {}
        for finding in findings:
            for paragraph in finding.paragraphs:
                if paragraph not in finding_items.keys():
                    finding_items[paragraph] = []
                finding_items[paragraph].append(finding.file)

        finding_items_list: List[Tuple[str, List[DocInfo]]] = list(
            finding_items.items()
        )
        finding_items_list.sort(
            key=lambda item: len(item[1]), reverse=True
        )  # 以语句在文件中出现次数多少排序
        # 遍历数据，为每个数据项创建一个子节点
        for i, finding_item in enumerate(finding_items_list):
            paragraph, files = finding_item
            unique_docinfos = self.doc_info_unique(files)
            unique_docinfos.sort(
                key=lambda doc_info: doc_info.modified_at, reverse=True
            )
            prefix = f"{i+1}.({len(unique_docinfos)}文件)："
            paragraph_id = self.tree.insert(
                "",
                "end",
                text=prefix
                + " " * (12 - len(prefix) if len(prefix) <= 12 else 0)
                + paragraph,
                values=paragraph,
            )

            for j, file in enumerate(unique_docinfos):
                self.tree.insert(
                    paragraph_id,
                    "end",
                    text=f"{j+1}. " + os.path.basename(file.name),
                    values=(file.name, paragraph),
                )
            # self.open_children_recursive(paragraph_id)
